package cn.ad.server.web.filter;

import cn.ad.server.common.utils.EncodeUtils;
import cn.ad.server.common.utils.SpringContextUtils;
import cn.ad.server.web.exception.AdServerMessageException;
import cn.ad.server.web.spring.model.sts.STSAdResponse;
import cn.ad.server.biz.internal.UserService;
import cn.ad.server.domain.ad.AppUser;
import cn.ad.server.domain.enumration.ReturnCode;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * @author dongbin.yu
 * @from 2016-06-06
 * @since V1.0
 */
public class TokenFilter implements Filter {

    private static Map<String, AppUser> appUserMap;

    protected final ObjectMapper objectMapper = new ObjectMapper();

    private UserService userService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        userService = SpringContextUtils.getBean(UserService.class);

        //初始化用户信息appId,appKey,status
        appUserMap = userService.findMapAppUser();

        //配置null过滤掉
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String token = httpRequest.getHeader("X-TOKEN");
        token = token == null ? "" : token;
        String message = "";

        String originString = EncodeUtils.base64Decode(token);
        String[] originList = originString.split("\\|");
        STSAdResponse adResponse = new STSAdResponse();

        try {
            validateToken(originList);
        } catch (AdServerMessageException e) {
            adResponse.setStatus(e.getReturnCode().getCode());
            adResponse.setMessage(e.getMessage());

            // 处理返回值
            response.setContentType("application/json;charset=utf-8");
            objectMapper.writeValue(response.getOutputStream(), adResponse);
            return;
        }

        chain.doFilter(request, response);

    }

    private void validateToken(String[] tokenString) {

        switch (tokenString.length) {

            case 3:
                String appId = tokenString[0];
                String time = tokenString[1];
                String sign = tokenString[2];

                AppUser appUser = appUserMap.get(appId);
                if (appUser == null) {
                    throw new AdServerMessageException(ReturnCode.E10009);
                } else {

                    //验证sign值
                    String currentSign = EncodeUtils.SHA1(appUser.getAppKey() + "|" + time);
                    if (!sign.equalsIgnoreCase(currentSign)) {
                        throw new AdServerMessageException(ReturnCode.E10011);
                    }

                }
                break;
            case 2:
                throw new AdServerMessageException(ReturnCode.E10012, "加密的格式不对,缺少sign");
            case 1:
                throw new AdServerMessageException(ReturnCode.E10012, "加密的格式不对,缺少sign和appKey");
            case 0:
                throw new AdServerMessageException(ReturnCode.E10012, "http header没有传递X-TOKEN");
        }

    }

    @Override
    public void destroy() {

    }
    
}
